--[[
pbInfo - Includes/inc.ChatLog.lua
	v0.41
	by p.b. a.k.a. novayuna
	released under the Creative Commons License By-Nc-Sa: http://creativecommons.org/licenses/by-nc-sa/3.0/
]]
function pbInfo.ChatLog.Scripts.OnLoad()
	if (type(pbInfo.ChatLog.Data["Whispers"]) ~= "table") then
		pbInfo.ChatLog.Data["Whispers"] = {};
	end;
	pbInfo.ChatLog.Timer = {}; --Game crashes if adding the first line too early (chat window was not initialized then) // true = once initialized this session; table = data for timer
	pbInfo.ChatLog.DB = {{},{},{},{},{},{},{},{},{},{}};
	pbInfo.ChatLog.File = "Log/log.pbInfo.Whispers.lua";
	pbInfo.ChatLog.Data["Whispers"] = TableTools.loadTable(pbInfo.ChatLog.File) or {};
end;

function pbInfo.ChatLog.Scripts.OnEvent(this, event, arg1, arg2)
	if (event == "CHAT_MSG_WHISPER") then -- arg1: text; arg2: buddy
		local text, buddy = arg1, string.match(arg2, "%[(%a+)%]");
		pbInfo.ChatLog.SaveMessage(buddy, buddy, text);
	elseif (event == "CHAT_MSN_OPEN") then -- arg1: Chat ID; arg2: buddy (if you write first, else not).
		local id, buddy = arg1, pbInfo.ChatLog.DB[arg1]["name"] or string.match(arg2, "%[(%a+)%]");
		if (type(pbInfo.ChatLog.Data["Whispers"][buddy]) == "table") then
			if (type(pbInfo.ChatLog.DB[arg1]["name"]) == "nil") then
				pbInfo.ChatLog.DB[arg1]["selfopened"] = true;
			end;
			pbInfo.ChatLog.ShowHistory(id, buddy, pbInfo.ChatLog.Data["Whispers"][buddy]);
		end;
		pbInfo.ChatLog.DB[arg1]["name"] = nil;
	elseif (event == "CHAT_MSN_POPUP") then
		pbInfo.ChatLog.DB[arg1]["name"] = string.match(arg2, "%[(%a+)%]"); -- save name applied to a chat window
	end;
end;

function pbInfo.ChatLog.Scripts.OnUpdate()
	local remainingDelays = false;
	for k, v in pairs(pbInfo.ChatLog.Timer) do
		if (type(v) == "table") then
			if (GetTime() >= v[1]) then
				pbInfo.ChatLog.Timer[k] = true;
				pbInfo.ChatLog.ShowHistory(unpack(v[2]));
			else
				remainingDelays = true;
			end;
		end;
	end;
	if (remainingDelays == false) then
		pbInfoChatLogTimer:Hide(); -- hiding frames disables their OnUpdate :).
	end;
end;

function pbInfo.ChatLog.SaveMessage(buddy, writer, text)
	if (pbIsEmpty(buddy)) then return; end;
	if (type(pbInfo.ChatLog.Data["Whispers"][buddy]) ~= "table") then
		pbInfo.ChatLog.Data["Whispers"][buddy] = {};
	end;
	table.insert(
		pbInfo.ChatLog.Data["Whispers"][buddy],
		{
			["time"] = os.time(),
			["writer"] = writer,
			["text"] = string.gsub(text, "|c%w%w%w%w%w%w%w%w(.-)|r", "%1");
		}
	);
	table.sort(pbInfo.ChatLog.Data["Whispers"][buddy], function(a, b) return a["time"] > b["time"] end);
	for k, _ in pairs(pbInfo.ChatLog.Data["Whispers"][buddy]) do
		if (k > pbInfoSettings["ChatLogMaxLinesPerChat"] + 1) then
			table.remove(pbInfo.ChatLog.Data["Whispers"][buddy], k);
		end;
	end;
--	TableTools.saveTable(pbInfo.ChatLog.Data["Whispers"], pbInfo.ChatLog.File);
end;

function pbInfo.ChatLog.ShowHistory(id, buddy, history)
	if (pbInfo.ChatLog.Timer[id] == true and not pbInfo.ChatLog.DB[id]["historyapplied"]) then
		table.sort(history, function(a, b) return a["time"] < b["time"] end);
		local num = #history;
		pbInfo.ChatLog.DB[id]["historyapplied"] = true;
		for k, v in pairs(history) do
			if (k == num and pbInfo.ChatLog.DB[id]["selfopened"] and not pbInfoChatLogTimer:IsVisible()) then
				pbInfo.ChatLog.DB[id]["selfopened"] = nil;
				break;
			end;
			pbInfo.ChatLog.AddMessage(id, v["time"], v["writer"], v["text"], (k < num));
		end;
	else
		pbInfo.ChatLog.Timer[id] = {GetTime() + 0.2, {id, buddy, history}};
		pbInfoChatLogTimer:Show();
	end;
end;

function pbInfo.ChatLog.AddMessage(id, timestamp, writer, message, history)
	local colors = {"00DDFF", "FFFFFF", "FF"};
	if (writer == UnitName("player")) then
		colors[1] = "DDFF00";
	end;
	if (history) then
		colors[3] = "AA";
	end;
	CRF_MsnWnd_AddMessage(_G["CRG_Chat" .. id], pbColor("[" .. os.date("%Y-%m-%d " .. pbInfoSettings["TimeStampFormat"], timestamp):lower() .. "] " .. writer, colors[1], colors[3])  .. ":\n" .. pbColor(message, colors[2], colors[3]), -1); -- for line count and scrolling options.. or sth. like that oO
--	Chat_AddMessage(id, pbColor("[" .. os.date("%Y-%m-%d %H:%M:%S", timestamp) .. "] " .. writer, colors[1], colors[3])  .. ":\n" .. pbColor(message, colors[2], colors[3]), -1);
end;

-- "Hooking" some functions by copying them; sorry for that... :/
pbInfo.Hooked.ChatEdit_SendText = ChatEdit_SendText;
function ChatEdit_SendText(editBox, addHistory)
	if (editBox.chatType == "WHISPER" and pbInfoSettings["CHATLOG"]) then
--		local chatID = editBox:GetParent():GetParent():GetID();
		local text, buddy = tostring(editBox:GetText()), tostring(editBox.tellTarget);
		if (string.len(string.gsub(text, "%s*(.+)", "%1")) > 0) then
			pbInfo.ChatLog.SaveMessage(buddy, UnitName("player"), text);
		end;
	end;
	pbInfo.Hooked.ChatEdit_SendText(editBox, addHistory);
end;

pbInfo.Hooked.CRF_TalkFrame_AddMessage = CRF_TalkFrame_AddMessage;
function CRF_TalkFrame_AddMessage(this, who, msg)
	if (type(pbInfoSettings) == "table" and pbInfoSettings["CHATLOG"] and type(pbInfo.ChatLog.DB) == "table" and type(pbInfo.ChatLog.DB[this:GetID()]) == "table") then
		if (pbInfoChatLogTimer:IsVisible() == false and pbInfo.ChatLog.DB[this:GetID()]["historyapplied"]) then 
			pbInfo.ChatLog.AddMessage(this:GetID(), os.time(), who, msg);
		end;
		return;
	end;
	pbInfo.Hooked.CRF_TalkFrame_AddMessage(this, who, msg);
end;

pbInfo.Hooked.CRF_MsnWnd_OnHide = CRF_MsnWnd_OnHide;
function CRF_MsnWnd_OnHide(this)
	pbInfo.ChatLog.DB[this:GetID()]["historyapplied"] = false;
	return pbInfo.Hooked.CRF_MsnWnd_OnHide(this);
end;